<!-- 登录页面 -->
<template>
  <q-layout>
    <q-header>
      <q-toolbar>
        <q-toolbar-title>{{ appTitle }} </q-toolbar-title>
        <q-btn :icon="$q.dark.isActive ? mdiWeatherNight : mdiWhiteBalanceSunny" flat dense round @click="changeTheme" />
      </q-toolbar>
    </q-header>

    <q-page-container>
      <q-page class="login-page">
        <q-card class="login-card fixed-center">
          <q-form @submit="handleLogin">
            <q-card-section class="q-py-sm">
              <div class="text-h6">登录 {{ appTitle }}</div>
            </q-card-section>

            <q-card-section class="q-py-sm">
              <!-- 用户名 -->
              <q-input v-model="form.username" label="用户名" :rules="rules.username" autofocus>
                <template #prepend><q-icon :name="mdiAccount" /></template>
              </q-input>

              <!-- 密码 -->
              <q-input v-model="form.password" :type="pwdType" :rules="rules.password" label="密 码" autocomplete @keyup="checkCapslock">
                <template #prepend><q-icon :name="mdiLock" /></template>
                <template #append>
                  <q-icon :name="showPwd ? mdiEyeOff : mdiEye" class="cursor-pointer" @click="showPwd = !showPwd" />
                </template>
                <q-tooltip v-if="isCapslock" v-model="isCapslock" anchor="top middle">大写锁定已打开</q-tooltip>
              </q-input>

              <!-- 验证码 -->
              <q-input v-if="showCaptcha" v-model="form.captcha" label="验证码" :rules="rules.captcha">
                <template #prepend><q-icon :name="mdiCheckCircle" /></template>
                <template #append>
                  <img :src="captchaSrc" height="40" class="cursor-pointer" @click="genCaptcha" />
                </template>
              </q-input>
            </q-card-section>

            <q-card-actions>
              <q-btn class="full-width" color="primary" :dense="false" :disable="loading" label="登&nbsp;&nbsp;&nbsp;录" type="submit" />
            </q-card-actions>
          </q-form>
        </q-card>
      </q-page>
    </q-page-container>
  </q-layout>
</template>

<script lang="ts" setup>
  import { ref, reactive, computed, onMounted } from 'vue';
  import { LocationQuery, useRoute, useRouter } from 'vue-router';
  import { useQuasar } from 'quasar';
  import { mdiWhiteBalanceSunny, mdiWeatherNight, mdiAccount, mdiLock, mdiEye, mdiEyeOff, mdiCheckCircle } from '@quasar/extras/mdi-v7';

  import { useUserStore, useSettingStore } from 'src/stores';
  import { LoginForm, getCaptcha } from 'src/api/login';

  // 定义组件名
  defineOptions({ name: 'LoginPage' });

  // 表单数据
  const appTitle = process.env.APP_TITLE;
  const form = reactive<LoginForm>({ username: 'admin', password: '123456', captcha: '', captchaKey: '' });
  const rules = {
    username: [(v: string) => !!v || '请输入用户名', (v: string) => v.length >= 3 || '最少三个字符'],
    password: [(v: string) => !!v || '请输入密码'],
    captcha: [(v: string) => !!v || '请输入验证码'],
  };

  // 是否大写锁定
  const isCapslock = ref(false);
  const checkCapslock = (e: KeyboardEvent) => {
    const { key } = e;
    isCapslock.value = (key && key.length === 1 && key >= 'A' && key <= 'Z') as boolean;
  };

  // 显示密码
  const showPwd = ref(false);
  const pwdType = computed(() => (showPwd.value ? 'text' : 'password'));

  // 验证码
  const showCaptcha = ref(false);
  const captchaSrc = ref('');
  const genCaptcha = () => {
    getCaptcha().then((data) => {
      showCaptcha.value = data.enabled;
      captchaSrc.value = 'data:image;base64,' + data.captcha;
      form.captchaKey = data.captchaKey as string;
    });
  };
  onMounted(genCaptcha);

  // 提交登录
  const loading = ref(false);
  const route = useRoute();
  const router = useRouter();
  const userStore = useUserStore();
  function handleLogin() {
    loading.value = true;
    userStore
      .doLogin(form)
      .then(() => {
        const query = route.query;
        const redirectQuery = getRedirectQuery(query);
        router.push({ path: (query.redirect as string) || '/', query: redirectQuery });
      })
      .finally(() => (loading.value = false));
  }

  function getRedirectQuery(query: LocationQuery) {
    const p: { [attr: string]: string } = {};
    Object.keys(query).forEach((k: string) => {
      if (k === 'redirect') {
        const index = query.redirect?.indexOf('?') ?? 0;
        if (index > 0) {
          const arr = (query.redirect as string).substring(index + 1).split('=');
          if (arr.length === 2) p[arr[0]] = arr[1];
        }
      } else {
        p[k] = query[k] as string;
      }
    });
    return p;
  }

  // 处理主题
  const $q = useQuasar();
  const setting = useSettingStore();
  function changeTheme() {
    setting.theme = $q.dark.isActive ? 'light' : 'dark';
  }
</script>

<style lang="scss" scoped>
  .login-page {
    background-color: lightgrey;
    .login-card {
      width: 380px;
      margin-top: -50px;
      padding: 8px;
    }
  }

  .body--dark {
    .login-page {
      background-color: $dark;
    }
  }
</style>
